#include "UtilCommon.h"

WowCrypt::WowCrypt()
{
	_initialized = false;
}

void WowCrypt::Init()
{
	_send_i = _send_j = _recv_i = _recv_j = 0;
	_initialized = true;
}

void WowCrypt::DecryptRecv(ui8 *data, size_t len)
{
	if (!_initialized) 
		return;
	if (len < CRYPTED_RECV_LEN) 
		return;
	_decrypt.Process(data, data, len);
}

void WowCrypt::DecryptSixRecv(ui8 *data)
{
    if (!_initialized) 
		return;
    _decrypt.Process(data, data, 6);
}

void WowCrypt::EncryptSend(ui8 *data, size_t len)
{
	if(!_initialized) 
		return;
	if(len < CRYPTED_SEND_LEN) 
		return;

	_encrypt.Process(data, data, len);
}

void WowCrypt::EncryptFourSend(ui8 * data)
{
    if (!_initialized) 
		return;
	_encrypt.Process(data, data, 4);
}

void WowCrypt::SetKey(ui8 *key, size_t len)
{
	_key.resize(len);
	std::copy(key, key + len, _key.begin());
}

void WowCrypt::GenerateKey(ui8 *sessionkey)
{
	const ui8 SeedKeyLen = 16;
    ui8 ServerEncryptionKey[SeedKeyLen] = { 0x22, 0xBE, 0xE5, 0xCF, 0xBB, 0x07, 0x64, 0xD9, 0x00, 0x45, 0x1B, 0xD0, 0x24, 0xB8, 0xD5, 0x45 };

	HMACHash auth;
	auth.Initialize(SeedKeyLen, (ui8*)ServerEncryptionKey);
	auth.UpdateData(sessionkey, 40);
	auth.Finalize();
	ui8 *encryptHash = auth.GetDigest();

    ui8 ServerDecryptionKey[SeedKeyLen] = { 0xF4, 0x66, 0x31, 0x59, 0xFC, 0x83, 0x6E, 0x31, 0x31, 0x02, 0x51, 0xD5, 0x44, 0x31, 0x67, 0x98 };
	HMACHash auth2;
	auth2.Initialize(SeedKeyLen, (ui8*)ServerDecryptionKey);
	auth2.UpdateData(sessionkey, 40);
	auth2.Finalize();
	ui8 *decryptHash = auth2.GetDigest();

    _decrypt.Setup((ui8*)decryptHash, 20);
    _encrypt.Setup((ui8*)encryptHash, 20);

	ui8 encryptRotateBuffer[1024];
    memset(encryptRotateBuffer, 0, 1024);
	_encrypt.Process((ui8*)encryptRotateBuffer, (ui8*)encryptRotateBuffer, 1024);

	ui8 decryptRotateBuffer[1024];
	memset(decryptRotateBuffer, 0, 1024);
	_decrypt.Process((ui8*)decryptRotateBuffer, (ui8*)decryptRotateBuffer, 1024);

    _initialized = true;
}

WowCrypt::~WowCrypt()
{
}